using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Office.Interop.Outlook;
using System.IO;
using Sucrose.Base;

namespace Sucrose.Output
{
    public class OutlookInterop : ISucroseOutput
    {
        private _Application outlookObj = new Application();

        /// <summary>
        /// Adds a task to Outlook
        /// </summary>
        /// <param name="task">The task to be added</param>
        /// <param name="lastImported">The date which the task was last imported</param>
        public void AddTask(Sucrose.Base.TaskItem task, DateTime lastImported)
        {
            Logger.Log("Adding task '" + task.Name + "'", MessageType.Debug);

            _TaskItem outlookTask = (_TaskItem)outlookObj.CreateItem(OlItemType.olTaskItem);

            outlookTask.Body        += "Course: " + task.Course.CourseName + Environment.NewLine;
            outlookTask.Body        += "Due Time: " + task.DueDate.ToShortTimeString() + Environment.NewLine + Environment.NewLine;
            outlookTask.Body        += task.Description;
            outlookTask.Body        += Environment.NewLine + Environment.NewLine + "Turn in: " + task.TurnInURL + Environment.NewLine + Environment.NewLine;
            outlookTask.DueDate     = task.DueDate;
            outlookTask.StartDate   = task.DueDate;
            outlookTask.Subject     = task.Name;
            outlookTask.Categories  = task.Course.CourseNumber;
            outlookTask.UserProperties.Add("TaskID", OlUserPropertyType.olInteger, true, 1);
            outlookTask.UserProperties["TaskID"].Value = task.Id;

            if (!String.IsNullOrEmpty(task.LocalLocation) && File.Exists(task.LocalLocation))
            {
                outlookTask.Attachments.Add(task.LocalLocation, OlAttachmentType.olByReference, 1, task.Filename);
            }

            outlookTask.Save();
        }

        /// <summary>
        /// Adds a grade notification to Outlook
        /// </summary>
        /// <param name="task">The TaskItem which has been graded</param>
        public void AddGrade(Sucrose.Base.TaskItem task)
        {
            _PostItem outlookPost = (_PostItem)outlookObj.CreateItem(OlItemType.olPostItem);

            /* ---This is a notification from Sucrose---
             * 
             * Assignment Name: __________
             * Grade: ___% - L
             * 
             * Class Name: ____________
             * Estimated Class Grade: ___% - L
             * Strict Class Grade:    ___% - L
             * 
             * Thank you for using Sucrose.
             */
            outlookPost.Subject = String.Format("{0:0.00}% ({1})", task.Grade, task.Course.PercentageToGrade(task.Grade / 100.0)) + " on " + task.Name;
            outlookPost.Categories = task.Course.CourseNumber;
            outlookPost.Body = String.Format
                            (  "---This is a notification from Sucrose---{0}"
                             + "{0}"
                             + "Assignment Name: {1}{0}"
                             + "Grade: {2:0.00}% - {3}{0}"
                             + "{0}"
                             + "Class Name: {4}{0}"
                             + "Estimated Class Grade: \t {5:0.00%} - {6}{0}"
                             + "Strict Class Grade: \t{7:0.00%} - {8}{0}"
                             + "{0}"
                             + "Thank you for using Sucrose.", 
                               
                             Environment.NewLine, 
                             task.Name,
                             task.Grade, 
                             task.Course.PercentageToGrade(task.Grade / 100.0), 
                             task.Course.CourseName, 
                             task.Course.EstimatedGradePercent, 
                             task.Course.EstimatedGradeLetter,
                             task.Course.GradePercent,
                             task.Course.GradeLetter
                            );
            outlookPost.UnRead = true;
            outlookPost.Save();
        }

        /// <summary>
        /// Checks if a task exists in Outlook. If it does, delete it so it can be re-added.
        /// </summary>
        /// <param name="task">The task to check against Outlook</param>
        /// <param name="lastRun">The date the task was last imported</param>
        /// <returns>True, if the task exists, false if it does not.</returns>
        public bool TaskExists(Sucrose.Base.TaskItem task, DateTime lastRun)
        {
            object missing = System.Reflection.Missing.Value;
            NameSpace outlookNS = outlookObj.GetNamespace("MAPI");
            MAPIFolder outlookTasks = outlookNS.GetDefaultFolder(OlDefaultFolders.olFolderTasks);

            foreach (_TaskItem outlookTask in outlookTasks.Items)
            {
                UserProperty outlookTaskId = outlookTask.UserProperties.Find("TaskID", missing);

                if (outlookTaskId != null && (int)outlookTaskId.Value == task.Id)
                {
                    if (
                        (lastRun != DateTime.MinValue && !outlookTask.Complete)
                        && (
                            (DateTime.Compare(task.LastModified, lastRun) > 0)
                            || (!String.IsNullOrEmpty(task.LocalLocation) && File.Exists(task.LocalLocation) && outlookTask.Attachments.Count < 1)
                           )
                       )
                    {
                        outlookTask.Delete();
                        return false;
                    }
                    else
                    {
                        Logger.Log(task.Name + " already exists, skipping...", MessageType.Debug);
                        return true;
                    }
                }
            }

            return false;
        }
    }
}
